package com.cloud.pole.user.service.impl;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.cloud.pole.api.user.BaseUserApi;
import com.cloud.pole.api.weixin.WxUserApi;
import com.cloud.pole.common.constant.CommonConstants;
import com.cloud.pole.common.constant.UserConstant;
import com.cloud.pole.common.exception.BaseException;
import com.cloud.pole.common.msg.ApiRestResponse;
import com.cloud.pole.common.util.DateUtils;
import com.cloud.pole.common.util.jwt.IJWTInfo;
import com.cloud.pole.common.util.jwt.JWTInfo;
import com.cloud.pole.common.util.jwt.JwtTokenUtil;
import com.cloud.pole.feign.IVerifyCodeService;
import com.cloud.pole.feign.IWxUserService;
import com.cloud.pole.user.biz.BaseUserBiz;
import com.cloud.pole.user.biz.CpChannelPersonBiz;
import com.cloud.pole.user.biz.authorized.UserAuthorizedWxBiz;
import com.cloud.pole.user.config.FileUploadConfiguration;
import com.cloud.pole.user.model.entity.BaseUser;
import com.cloud.pole.user.model.entity.authorized.UserAuthorizedWx;
import com.cloud.pole.user.service.UserService;
import com.cloud.pole.util.ChannelPersonUtil;

@Service
public class UserServiceImpl implements UserService {
    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12);

    @Autowired
    private BaseUserBiz baseUserBiz;
    
    @Autowired
    private IVerifyCodeService verifyCodeService;
    
	@Autowired
	FileUploadConfiguration fileUploadConfiguration;

	@Autowired
	IWxUserService  wxUserService;
	
	@Autowired
	UserAuthorizedWxBiz userAuthorizedWxBiz;
	
	@Autowired
	private CpChannelPersonBiz channelPersonBiz;
	
	/**
	 * 用户注册
	 * @param mobile
	 * @param verifyCode
	 * @param loginPwd
	 * @param mobileArea
	 * @return
	 */
	public BaseUserApi userRegister(String mobile, String userName, String verifyCode, String loginPwd, String mobileArea, String openId, String originTag,  int clientType) throws Exception {	
		BaseUserApi baseUserVo = new BaseUserApi();
		//手机不能重复注册
		BaseUser userParam = new BaseUser();
		userParam.setUserName(userName);
		BaseUser baseUser = baseUserBiz.selectOne(userParam);
		if(baseUser != null) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "账号已经存在，请修改用户名");
		}
		if(!StringUtils.isEmpty(mobile)) {
			userParam = new BaseUser();
			userParam.setMobile(mobile);
			userParam.setMobileArea(mobileArea);
			baseUser = baseUserBiz.selectOne(userParam);
			if(baseUser != null) {
				throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "手机号码已经绑定，不能重复绑定");
			}
		}
		WxUserApi wxUserApi = null;
		UserAuthorizedWx userAuthorizedWx = null;
		if(!StringUtils.isEmpty(openId)) {
			//获取微信用户信息
			ApiRestResponse<WxUserApi> apiRestResponse =  wxUserService.getWxUser(openId);
			if(apiRestResponse.getStatus() != CommonConstants.STATUS_OK_CODE) {
				throw new BaseException(apiRestResponse.getStatus(), apiRestResponse.getMessage());
			}
		    wxUserApi = apiRestResponse.getData();
		    if(wxUserApi == null) {
				throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "openId错误");
		    }
			//微信授权查看是否授权给其他账户，暂时未实现
		    userAuthorizedWx =  userAuthorizedWxBiz.selectByOpenId(openId);
		    if(userAuthorizedWx != null) {
				throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "微信账号已经绑定了其他手机");
		    }
		}
		//判断验证码是否有效
		ApiRestResponse<Boolean> checkResponse = verifyCodeService.checkVerifyCode(mobileArea, mobile, UserConstant.VERIFY_CODE_REG, verifyCode);
		if(checkResponse.getStatus() != CommonConstants.STATUS_OK_CODE) {
			throw new BaseException(checkResponse.getStatus(), checkResponse.getMessage());
		}
		Boolean checkResult = checkResponse.getData();
		if(checkResult.booleanValue() == false) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "验证码错误");
		}
		String userNickName = mobile.substring(0 , 3) + "****" + mobile.substring(7 , mobile.length());
		baseUser = new BaseUser();
		if(wxUserApi != null) {
			if(!StringUtils.isEmpty(wxUserApi.getNickName())) {
				userNickName = wxUserApi.getNickName();
			}
			baseUser.setSex(wxUserApi.getGender());
			baseUser.setHandIdcard(wxUserApi.getAvatarUrl());
		}
		baseUser.setMobile(mobile);
		baseUser.setUserName(userName);
		baseUser.setPassWord(loginPwd);
		baseUser.setMobileArea(mobileArea);
		baseUser.setCreateTime(new Date());
		baseUser.setOriginTag(originTag);
		baseUser.setUserStatus(BaseUser.USER_STATUS_EFFECTIVE);
		baseUser.setNickName(userNickName);
		//查询cp_channel_person有没有对应的手机号
		ChannelPersonUtil.checkChannelPerson(mobile, baseUser, channelPersonBiz);
		
		baseUserBiz.insertUseGeneratedKeys(baseUser);
		//绑定微信
		if(wxUserApi != null) {
			userAuthorizedWx = new UserAuthorizedWx();
			userAuthorizedWx.setAppId(wxUserApi.getAppId());
			userAuthorizedWx.setAuthorizedNote("");
			userAuthorizedWx.setAuthorizedStatus(UserAuthorizedWx.AUTHORIZED_STATUS_OK);
			userAuthorizedWx.setAuthorizedTime(new Date());
			userAuthorizedWx.setOpenId(wxUserApi.getOpenId());
			userAuthorizedWx.setUserId(baseUser.getUserId());
			userAuthorizedWx.setUserName(baseUser.getUserName());
			userAuthorizedWx.setWxAppId(wxUserApi.getWxAppId());
			userAuthorizedWxBiz.insert(userAuthorizedWx);
		}
		BeanUtils.copyProperties(baseUser, baseUserVo);
		return baseUserVo;
	}

	@Override
	public void modifyLoginPwd(String loginPwd, String newLoginPwd, String token) throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jtwInfo = JwtTokenUtil.getInfoFromToken(token);
		//验证用户
		BaseUser baseUser = baseUserBiz.getUserByUserName(jtwInfo.getUniqueName());
		if(baseUser == null) {
			throw new BaseException(CommonConstants.USER_STATUS_ERROR, CommonConstants.USER_STATUS_ERROR_MESSAGE);
		}
		if(!encoder.matches(loginPwd, baseUser.getPassWord())){                     
			throw new BaseException(CommonConstants.USER_PWD_ERROR, CommonConstants.USER_PWD_ERROR_MESSAGE);
		}
		baseUser.setPassWord(encoder.encode(newLoginPwd));
		baseUserBiz.updateSelectiveById(baseUser);
	}

	@Override
	public void forgetLoginPwd(String mobile, String mobileArea, String verifyCode, String newLoginPwd) throws Exception {
		// TODO Auto-generated method stub
		// 验证用户
		BaseUser userParam = new BaseUser();
		userParam.setMobile(mobile);
		userParam.setMobileArea(mobileArea);
		BaseUser baseUser = baseUserBiz.selectOne(userParam);
		if(baseUser == null) {
			throw new BaseException(CommonConstants.USER_STATUS_ERROR, CommonConstants.USER_STATUS_ERROR_MESSAGE);
		}
		//判断验证码是否有效
		ApiRestResponse<Boolean> checkResponse = verifyCodeService.checkVerifyCode(mobileArea, mobile, UserConstant.VERIFY_CODE_FORGET_LOGIN_PWD, verifyCode);
		if(checkResponse.getStatus() != CommonConstants.STATUS_OK_CODE) {
			throw new BaseException(checkResponse.getStatus(), checkResponse.getMessage());
		}
		Boolean checkResult = checkResponse.getData();
		if(checkResult.booleanValue() == false) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "验证码错误");
		}

		// 更新用户安全密码
		baseUser.setPassWord(encoder.encode(newLoginPwd));
		baseUserBiz.updateSelectiveById(baseUser);
	}
	
	/**
	 * 检测用户是否存在 
	 *
	 */
	@Override
	public boolean checkUserExistsByMobile(String mobileArea, String mobile) throws Exception {
		// TODO Auto-generated method stub
		boolean result = false;
		BaseUser userParam = new BaseUser();
		userParam.setMobile(mobile);
		userParam.setMobileArea(mobileArea);
		BaseUser baseUser = baseUserBiz.selectOne(userParam);
		if(baseUser != null) {
			result = true;
		}
		return result;
	}

	@Override
	public boolean checkPayPwd(String token, String payPwd) throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jtwInfo = JwtTokenUtil.getInfoFromToken(token);
		BaseUser baseUser = baseUserBiz.getUserByUserName(jtwInfo.getUniqueName());
		//验证用户
		if(baseUser == null) {
			throw new BaseException(CommonConstants.USER_STATUS_ERROR, CommonConstants.USER_STATUS_ERROR_MESSAGE);
		}
		if(baseUser.getIsPayDisable() == BaseUser.IS_PAY_DISABLE_YES) {
			throw new BaseException(CommonConstants.USER_PAY_DISABLE_ERROR, CommonConstants.USER_PAY_DISABLE_ERROR_MESSAGE);
		}
		if(!encoder.matches(payPwd, baseUser.getPayPwd())){                     
			throw new BaseException(CommonConstants.USER_PAYPWD_ERROR, CommonConstants.USER_PAYPWD_ERROR_MESSAGE);
		}
		return true;
	}

	@Override
	public void modifyPayPwd(String payPwd, String newPayPwd, String token) throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jtwInfo = JwtTokenUtil.getInfoFromToken(token);
		//验证用户
		BaseUser baseUser = baseUserBiz.getUserByUserName(jtwInfo.getUniqueName());
		if(baseUser == null) {
			throw new BaseException(CommonConstants.USER_STATUS_ERROR, CommonConstants.USER_STATUS_ERROR_MESSAGE);
		}
		if(!encoder.matches(payPwd, baseUser.getPayPwd())){                     
			throw new BaseException(CommonConstants.USER_PAYPWD_ERROR, CommonConstants.USER_PAYPWD_ERROR_MESSAGE);
		}
		baseUser.setPayPwd(encoder.encode(newPayPwd));
		baseUserBiz.updateSelectiveById(baseUser);		
	}

	@Override
	public void forgetPayPwd(String mobile, String mobileArea, String verifyCode, String newPayPwd) throws Exception {
		// TODO Auto-generated method stub
		// 验证用户
		BaseUser userParam = new BaseUser();
		userParam.setMobile(mobile);
		userParam.setMobileArea(mobileArea);
		BaseUser baseUser = baseUserBiz.selectOne(userParam);
		if(baseUser == null) {
			throw new BaseException(CommonConstants.USER_STATUS_ERROR, CommonConstants.USER_STATUS_ERROR_MESSAGE);
		}
		//判断验证码是否有效
		ApiRestResponse<Boolean> checkResponse = verifyCodeService.checkVerifyCode(mobileArea, mobile, UserConstant.VERIFY_CODE_FORGET_PAY_PWD, verifyCode);
		if(checkResponse.getStatus() != CommonConstants.STATUS_OK_CODE) {
			throw new BaseException(checkResponse.getStatus(), checkResponse.getMessage());
		}
		Boolean checkResult = checkResponse.getData();
		if(checkResult.booleanValue() == false) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "验证码错误");
		}

		// 更新用户安全密码
		baseUser.setPayPwd(encoder.encode(newPayPwd));
		baseUserBiz.updateSelectiveById(baseUser);		
	}

	@Override
	public BaseUserApi getBaseUser(String token) throws Exception {
		// TODO Auto-generated method stub
    	JWTInfo jwtInfo = (JWTInfo)JwtTokenUtil.getInfoFromToken(token);
    	BaseUser user = baseUserBiz.getUserByUserName(jwtInfo.getUniqueName());
    	BaseUserApi userVo = new BaseUserApi();
        BeanUtils.copyProperties(user, userVo);
		return userVo;
	}

	@Override
	public boolean modifyUser(String token, String iconPath, String realName, String sex, String birthday, String provinceId,
			String provinceName, String cityId, String cityName, String districtId, String districtName, String weixin)
			throws Exception {
    	JWTInfo jwtInfo = (JWTInfo)JwtTokenUtil.getInfoFromToken(token);
    	BaseUser user = baseUserBiz.getUserByUserName(jwtInfo.getUniqueName());
    	if(user == null) {
			throw new BaseException(CommonConstants.USER_STATUS_ERROR, CommonConstants.USER_STATUS_ERROR_MESSAGE);
		}
    	boolean hasParam = false;
    	if(!StringUtils.isEmpty(iconPath)) {
    		if(!iconPath.startsWith("http")){
    			iconPath = fileUploadConfiguration.getImageUrl() + iconPath;
    		}
        	user.setIconPath(iconPath);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(realName)) {
        	user.setRealName(realName);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(sex)) {
        	user.setSex(Integer.parseInt(sex));
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(birthday)) {
    		if(! DateUtils.isValidDate(birthday, "yyyy-MM-dd")) {
    			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "日期格式错误");
    		}
        	user.setBirthday(birthday);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(provinceId)) {
        	user.setProvinceId(provinceId);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(provinceName)) {
        	user.setProvinceName(provinceName);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(cityId)) {
        	user.setCityId(cityId);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(cityName)) {
        	user.setCityName(cityName);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(districtId)) {
        	user.setDistrictId(districtId);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(districtName)) {
        	user.setDistrictName(districtName);
        	hasParam = true;
    	}
    	if(!StringUtils.isEmpty(weixin)) {
        	user.setWeixin(weixin);
        	hasParam = true;
    	}
    	if(!hasParam) {
			throw new BaseException(CommonConstants.STATUS_ERROR_CODE, "参数为空");
    	}
    	baseUserBiz.updateSelectiveById(user);
    	return true;
	}

	@Override
	public boolean loginOut(String token) throws Exception {
		// TODO Auto-generated method stub
		IJWTInfo jtwInfo = JwtTokenUtil.getInfoFromToken(token);
		BaseUser baseUser = baseUserBiz.getUserByUserName(jtwInfo.getUniqueName());
		return true;
	}

	@Override
	public BaseUserApi getUserByMobile(String mobileArea, String mobile) throws Exception {
		// TODO Auto-generated method stub
		BaseUser userParam = new BaseUser();
		userParam.setMobile(mobile);
		userParam.setMobileArea(mobileArea);
		BaseUser baseUser = baseUserBiz.selectOne(userParam);
		BaseUserApi userApi = null;
		if(baseUser != null) {
			userApi = new BaseUserApi();
			BeanUtils.copyProperties(baseUser, userApi);
		}		
		return userApi;
	}

	@Override
	public BaseUserApi getUserByMarketCode(String marketCode) {
		BaseUser userParam = new BaseUser();
		userParam.setMarketCode(marketCode);
		BaseUser baseUser = baseUserBiz.selectOne(userParam);
		BaseUserApi userApi = null;
		if(baseUser != null) {
			userApi = new BaseUserApi();
			BeanUtils.copyProperties(baseUser, userApi);
		}		
		return userApi;
	}
}
